(function (factory) {
	typeof define === 'function' && define.amd ? define(factory) :
	factory();
})((function () { 'use strict';

	var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

	var browserPolyfill = {exports: {}};

	(function (module, exports) {
	(function (global, factory) {
	  {
	    factory(module);
	  }
	})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : commonjsGlobal, function (module) {

	  if (typeof browser === "undefined" || Object.getPrototypeOf(browser) !== Object.prototype) {
	    const CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE = "The message port closed before a response was received.";
	    const SEND_RESPONSE_DEPRECATION_WARNING = "Returning a Promise is the preferred way to send a reply from an onMessage/onMessageExternal listener, as the sendResponse will be removed from the specs (See https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage)"; // Wrapping the bulk of this polyfill in a one-time-use function is a minor
	    // optimization for Firefox. Since Spidermonkey does not fully parse the
	    // contents of a function until the first time it's called, and since it will
	    // never actually need to be called, this allows the polyfill to be included
	    // in Firefox nearly for free.

	    const wrapAPIs = extensionAPIs => {
	      // NOTE: apiMetadata is associated to the content of the api-metadata.json file
	      // at build time by replacing the following "include" with the content of the
	      // JSON file.
	      const apiMetadata = {
	        "alarms": {
	          "clear": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "clearAll": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "get": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "getAll": {
	            "minArgs": 0,
	            "maxArgs": 0
	          }
	        },
	        "bookmarks": {
	          "create": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "get": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getChildren": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getRecent": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getSubTree": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getTree": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "move": {
	            "minArgs": 2,
	            "maxArgs": 2
	          },
	          "remove": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeTree": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "search": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "update": {
	            "minArgs": 2,
	            "maxArgs": 2
	          }
	        },
	        "browserAction": {
	          "disable": {
	            "minArgs": 0,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "enable": {
	            "minArgs": 0,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "getBadgeBackgroundColor": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getBadgeText": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getPopup": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getTitle": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "openPopup": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "setBadgeBackgroundColor": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "setBadgeText": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "setIcon": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "setPopup": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "setTitle": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          }
	        },
	        "browsingData": {
	          "remove": {
	            "minArgs": 2,
	            "maxArgs": 2
	          },
	          "removeCache": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeCookies": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeDownloads": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeFormData": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeHistory": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeLocalStorage": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removePasswords": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removePluginData": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "settings": {
	            "minArgs": 0,
	            "maxArgs": 0
	          }
	        },
	        "commands": {
	          "getAll": {
	            "minArgs": 0,
	            "maxArgs": 0
	          }
	        },
	        "contextMenus": {
	          "remove": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeAll": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "update": {
	            "minArgs": 2,
	            "maxArgs": 2
	          }
	        },
	        "cookies": {
	          "get": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getAll": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getAllCookieStores": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "remove": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "set": {
	            "minArgs": 1,
	            "maxArgs": 1
	          }
	        },
	        "devtools": {
	          "inspectedWindow": {
	            "eval": {
	              "minArgs": 1,
	              "maxArgs": 2,
	              "singleCallbackArg": false
	            }
	          },
	          "panels": {
	            "create": {
	              "minArgs": 3,
	              "maxArgs": 3,
	              "singleCallbackArg": true
	            },
	            "elements": {
	              "createSidebarPane": {
	                "minArgs": 1,
	                "maxArgs": 1
	              }
	            }
	          }
	        },
	        "downloads": {
	          "cancel": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "download": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "erase": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getFileIcon": {
	            "minArgs": 1,
	            "maxArgs": 2
	          },
	          "open": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "pause": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeFile": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "resume": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "search": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "show": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          }
	        },
	        "extension": {
	          "isAllowedFileSchemeAccess": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "isAllowedIncognitoAccess": {
	            "minArgs": 0,
	            "maxArgs": 0
	          }
	        },
	        "history": {
	          "addUrl": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "deleteAll": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "deleteRange": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "deleteUrl": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getVisits": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "search": {
	            "minArgs": 1,
	            "maxArgs": 1
	          }
	        },
	        "i18n": {
	          "detectLanguage": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getAcceptLanguages": {
	            "minArgs": 0,
	            "maxArgs": 0
	          }
	        },
	        "identity": {
	          "launchWebAuthFlow": {
	            "minArgs": 1,
	            "maxArgs": 1
	          }
	        },
	        "idle": {
	          "queryState": {
	            "minArgs": 1,
	            "maxArgs": 1
	          }
	        },
	        "management": {
	          "get": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getAll": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "getSelf": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "setEnabled": {
	            "minArgs": 2,
	            "maxArgs": 2
	          },
	          "uninstallSelf": {
	            "minArgs": 0,
	            "maxArgs": 1
	          }
	        },
	        "notifications": {
	          "clear": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "create": {
	            "minArgs": 1,
	            "maxArgs": 2
	          },
	          "getAll": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "getPermissionLevel": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "update": {
	            "minArgs": 2,
	            "maxArgs": 2
	          }
	        },
	        "pageAction": {
	          "getPopup": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getTitle": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "hide": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "setIcon": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "setPopup": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "setTitle": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          },
	          "show": {
	            "minArgs": 1,
	            "maxArgs": 1,
	            "fallbackToNoCallback": true
	          }
	        },
	        "permissions": {
	          "contains": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getAll": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "remove": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "request": {
	            "minArgs": 1,
	            "maxArgs": 1
	          }
	        },
	        "runtime": {
	          "getBackgroundPage": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "getPlatformInfo": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "openOptionsPage": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "requestUpdateCheck": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "sendMessage": {
	            "minArgs": 1,
	            "maxArgs": 3
	          },
	          "sendNativeMessage": {
	            "minArgs": 2,
	            "maxArgs": 2
	          },
	          "setUninstallURL": {
	            "minArgs": 1,
	            "maxArgs": 1
	          }
	        },
	        "sessions": {
	          "getDevices": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "getRecentlyClosed": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "restore": {
	            "minArgs": 0,
	            "maxArgs": 1
	          }
	        },
	        "storage": {
	          "local": {
	            "clear": {
	              "minArgs": 0,
	              "maxArgs": 0
	            },
	            "get": {
	              "minArgs": 0,
	              "maxArgs": 1
	            },
	            "getBytesInUse": {
	              "minArgs": 0,
	              "maxArgs": 1
	            },
	            "remove": {
	              "minArgs": 1,
	              "maxArgs": 1
	            },
	            "set": {
	              "minArgs": 1,
	              "maxArgs": 1
	            }
	          },
	          "managed": {
	            "get": {
	              "minArgs": 0,
	              "maxArgs": 1
	            },
	            "getBytesInUse": {
	              "minArgs": 0,
	              "maxArgs": 1
	            }
	          },
	          "sync": {
	            "clear": {
	              "minArgs": 0,
	              "maxArgs": 0
	            },
	            "get": {
	              "minArgs": 0,
	              "maxArgs": 1
	            },
	            "getBytesInUse": {
	              "minArgs": 0,
	              "maxArgs": 1
	            },
	            "remove": {
	              "minArgs": 1,
	              "maxArgs": 1
	            },
	            "set": {
	              "minArgs": 1,
	              "maxArgs": 1
	            }
	          }
	        },
	        "tabs": {
	          "captureVisibleTab": {
	            "minArgs": 0,
	            "maxArgs": 2
	          },
	          "create": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "detectLanguage": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "discard": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "duplicate": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "executeScript": {
	            "minArgs": 1,
	            "maxArgs": 2
	          },
	          "get": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getCurrent": {
	            "minArgs": 0,
	            "maxArgs": 0
	          },
	          "getZoom": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "getZoomSettings": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "goBack": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "goForward": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "highlight": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "insertCSS": {
	            "minArgs": 1,
	            "maxArgs": 2
	          },
	          "move": {
	            "minArgs": 2,
	            "maxArgs": 2
	          },
	          "query": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "reload": {
	            "minArgs": 0,
	            "maxArgs": 2
	          },
	          "remove": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "removeCSS": {
	            "minArgs": 1,
	            "maxArgs": 2
	          },
	          "sendMessage": {
	            "minArgs": 2,
	            "maxArgs": 3
	          },
	          "setZoom": {
	            "minArgs": 1,
	            "maxArgs": 2
	          },
	          "setZoomSettings": {
	            "minArgs": 1,
	            "maxArgs": 2
	          },
	          "update": {
	            "minArgs": 1,
	            "maxArgs": 2
	          }
	        },
	        "topSites": {
	          "get": {
	            "minArgs": 0,
	            "maxArgs": 0
	          }
	        },
	        "webNavigation": {
	          "getAllFrames": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "getFrame": {
	            "minArgs": 1,
	            "maxArgs": 1
	          }
	        },
	        "webRequest": {
	          "handlerBehaviorChanged": {
	            "minArgs": 0,
	            "maxArgs": 0
	          }
	        },
	        "windows": {
	          "create": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "get": {
	            "minArgs": 1,
	            "maxArgs": 2
	          },
	          "getAll": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "getCurrent": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "getLastFocused": {
	            "minArgs": 0,
	            "maxArgs": 1
	          },
	          "remove": {
	            "minArgs": 1,
	            "maxArgs": 1
	          },
	          "update": {
	            "minArgs": 2,
	            "maxArgs": 2
	          }
	        }
	      };

	      if (Object.keys(apiMetadata).length === 0) {
	        throw new Error("api-metadata.json has not been included in browser-polyfill");
	      }
	      /**
	       * A WeakMap subclass which creates and stores a value for any key which does
	       * not exist when accessed, but behaves exactly as an ordinary WeakMap
	       * otherwise.
	       *
	       * @param {function} createItem
	       *        A function which will be called in order to create the value for any
	       *        key which does not exist, the first time it is accessed. The
	       *        function receives, as its only argument, the key being created.
	       */


	      class DefaultWeakMap extends WeakMap {
	        constructor(createItem, items = undefined) {
	          super(items);
	          this.createItem = createItem;
	        }

	        get(key) {
	          if (!this.has(key)) {
	            this.set(key, this.createItem(key));
	          }

	          return super.get(key);
	        }

	      }
	      /**
	       * Returns true if the given object is an object with a `then` method, and can
	       * therefore be assumed to behave as a Promise.
	       *
	       * @param {*} value The value to test.
	       * @returns {boolean} True if the value is thenable.
	       */


	      const isThenable = value => {
	        return value && typeof value === "object" && typeof value.then === "function";
	      };
	      /**
	       * Creates and returns a function which, when called, will resolve or reject
	       * the given promise based on how it is called:
	       *
	       * - If, when called, `chrome.runtime.lastError` contains a non-null object,
	       *   the promise is rejected with that value.
	       * - If the function is called with exactly one argument, the promise is
	       *   resolved to that value.
	       * - Otherwise, the promise is resolved to an array containing all of the
	       *   function's arguments.
	       *
	       * @param {object} promise
	       *        An object containing the resolution and rejection functions of a
	       *        promise.
	       * @param {function} promise.resolve
	       *        The promise's resolution function.
	       * @param {function} promise.reject
	       *        The promise's rejection function.
	       * @param {object} metadata
	       *        Metadata about the wrapped method which has created the callback.
	       * @param {boolean} metadata.singleCallbackArg
	       *        Whether or not the promise is resolved with only the first
	       *        argument of the callback, alternatively an array of all the
	       *        callback arguments is resolved. By default, if the callback
	       *        function is invoked with only a single argument, that will be
	       *        resolved to the promise, while all arguments will be resolved as
	       *        an array if multiple are given.
	       *
	       * @returns {function}
	       *        The generated callback function.
	       */


	      const makeCallback = (promise, metadata) => {
	        return (...callbackArgs) => {
	          if (extensionAPIs.runtime.lastError) {
	            promise.reject(new Error(extensionAPIs.runtime.lastError.message));
	          } else if (metadata.singleCallbackArg || callbackArgs.length <= 1 && metadata.singleCallbackArg !== false) {
	            promise.resolve(callbackArgs[0]);
	          } else {
	            promise.resolve(callbackArgs);
	          }
	        };
	      };

	      const pluralizeArguments = numArgs => numArgs == 1 ? "argument" : "arguments";
	      /**
	       * Creates a wrapper function for a method with the given name and metadata.
	       *
	       * @param {string} name
	       *        The name of the method which is being wrapped.
	       * @param {object} metadata
	       *        Metadata about the method being wrapped.
	       * @param {integer} metadata.minArgs
	       *        The minimum number of arguments which must be passed to the
	       *        function. If called with fewer than this number of arguments, the
	       *        wrapper will raise an exception.
	       * @param {integer} metadata.maxArgs
	       *        The maximum number of arguments which may be passed to the
	       *        function. If called with more than this number of arguments, the
	       *        wrapper will raise an exception.
	       * @param {boolean} metadata.singleCallbackArg
	       *        Whether or not the promise is resolved with only the first
	       *        argument of the callback, alternatively an array of all the
	       *        callback arguments is resolved. By default, if the callback
	       *        function is invoked with only a single argument, that will be
	       *        resolved to the promise, while all arguments will be resolved as
	       *        an array if multiple are given.
	       *
	       * @returns {function(object, ...*)}
	       *       The generated wrapper function.
	       */


	      const wrapAsyncFunction = (name, metadata) => {
	        return function asyncFunctionWrapper(target, ...args) {
	          if (args.length < metadata.minArgs) {
	            throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`);
	          }

	          if (args.length > metadata.maxArgs) {
	            throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`);
	          }

	          return new Promise((resolve, reject) => {
	            if (metadata.fallbackToNoCallback) {
	              // This API method has currently no callback on Chrome, but it return a promise on Firefox,
	              // and so the polyfill will try to call it with a callback first, and it will fallback
	              // to not passing the callback if the first call fails.
	              try {
	                target[name](...args, makeCallback({
	                  resolve,
	                  reject
	                }, metadata));
	              } catch (cbError) {
	                console.warn(`${name} API method doesn't seem to support the callback parameter, ` + "falling back to call it without a callback: ", cbError);
	                target[name](...args); // Update the API method metadata, so that the next API calls will not try to
	                // use the unsupported callback anymore.

	                metadata.fallbackToNoCallback = false;
	                metadata.noCallback = true;
	                resolve();
	              }
	            } else if (metadata.noCallback) {
	              target[name](...args);
	              resolve();
	            } else {
	              target[name](...args, makeCallback({
	                resolve,
	                reject
	              }, metadata));
	            }
	          });
	        };
	      };
	      /**
	       * Wraps an existing method of the target object, so that calls to it are
	       * intercepted by the given wrapper function. The wrapper function receives,
	       * as its first argument, the original `target` object, followed by each of
	       * the arguments passed to the original method.
	       *
	       * @param {object} target
	       *        The original target object that the wrapped method belongs to.
	       * @param {function} method
	       *        The method being wrapped. This is used as the target of the Proxy
	       *        object which is created to wrap the method.
	       * @param {function} wrapper
	       *        The wrapper function which is called in place of a direct invocation
	       *        of the wrapped method.
	       *
	       * @returns {Proxy<function>}
	       *        A Proxy object for the given method, which invokes the given wrapper
	       *        method in its place.
	       */


	      const wrapMethod = (target, method, wrapper) => {
	        return new Proxy(method, {
	          apply(targetMethod, thisObj, args) {
	            return wrapper.call(thisObj, target, ...args);
	          }

	        });
	      };

	      let hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
	      /**
	       * Wraps an object in a Proxy which intercepts and wraps certain methods
	       * based on the given `wrappers` and `metadata` objects.
	       *
	       * @param {object} target
	       *        The target object to wrap.
	       *
	       * @param {object} [wrappers = {}]
	       *        An object tree containing wrapper functions for special cases. Any
	       *        function present in this object tree is called in place of the
	       *        method in the same location in the `target` object tree. These
	       *        wrapper methods are invoked as described in {@see wrapMethod}.
	       *
	       * @param {object} [metadata = {}]
	       *        An object tree containing metadata used to automatically generate
	       *        Promise-based wrapper functions for asynchronous. Any function in
	       *        the `target` object tree which has a corresponding metadata object
	       *        in the same location in the `metadata` tree is replaced with an
	       *        automatically-generated wrapper function, as described in
	       *        {@see wrapAsyncFunction}
	       *
	       * @returns {Proxy<object>}
	       */

	      const wrapObject = (target, wrappers = {}, metadata = {}) => {
	        let cache = Object.create(null);
	        let handlers = {
	          has(proxyTarget, prop) {
	            return prop in target || prop in cache;
	          },

	          get(proxyTarget, prop, receiver) {
	            if (prop in cache) {
	              return cache[prop];
	            }

	            if (!(prop in target)) {
	              return undefined;
	            }

	            let value = target[prop];

	            if (typeof value === "function") {
	              // This is a method on the underlying object. Check if we need to do
	              // any wrapping.
	              if (typeof wrappers[prop] === "function") {
	                // We have a special-case wrapper for this method.
	                value = wrapMethod(target, target[prop], wrappers[prop]);
	              } else if (hasOwnProperty(metadata, prop)) {
	                // This is an async method that we have metadata for. Create a
	                // Promise wrapper for it.
	                let wrapper = wrapAsyncFunction(prop, metadata[prop]);
	                value = wrapMethod(target, target[prop], wrapper);
	              } else {
	                // This is a method that we don't know or care about. Return the
	                // original method, bound to the underlying object.
	                value = value.bind(target);
	              }
	            } else if (typeof value === "object" && value !== null && (hasOwnProperty(wrappers, prop) || hasOwnProperty(metadata, prop))) {
	              // This is an object that we need to do some wrapping for the children
	              // of. Create a sub-object wrapper for it with the appropriate child
	              // metadata.
	              value = wrapObject(value, wrappers[prop], metadata[prop]);
	            } else if (hasOwnProperty(metadata, "*")) {
	              // Wrap all properties in * namespace.
	              value = wrapObject(value, wrappers[prop], metadata["*"]);
	            } else {
	              // We don't need to do any wrapping for this property,
	              // so just forward all access to the underlying object.
	              Object.defineProperty(cache, prop, {
	                configurable: true,
	                enumerable: true,

	                get() {
	                  return target[prop];
	                },

	                set(value) {
	                  target[prop] = value;
	                }

	              });
	              return value;
	            }

	            cache[prop] = value;
	            return value;
	          },

	          set(proxyTarget, prop, value, receiver) {
	            if (prop in cache) {
	              cache[prop] = value;
	            } else {
	              target[prop] = value;
	            }

	            return true;
	          },

	          defineProperty(proxyTarget, prop, desc) {
	            return Reflect.defineProperty(cache, prop, desc);
	          },

	          deleteProperty(proxyTarget, prop) {
	            return Reflect.deleteProperty(cache, prop);
	          }

	        }; // Per contract of the Proxy API, the "get" proxy handler must return the
	        // original value of the target if that value is declared read-only and
	        // non-configurable. For this reason, we create an object with the
	        // prototype set to `target` instead of using `target` directly.
	        // Otherwise we cannot return a custom object for APIs that
	        // are declared read-only and non-configurable, such as `chrome.devtools`.
	        //
	        // The proxy handlers themselves will still use the original `target`
	        // instead of the `proxyTarget`, so that the methods and properties are
	        // dereferenced via the original targets.

	        let proxyTarget = Object.create(target);
	        return new Proxy(proxyTarget, handlers);
	      };
	      /**
	       * Creates a set of wrapper functions for an event object, which handles
	       * wrapping of listener functions that those messages are passed.
	       *
	       * A single wrapper is created for each listener function, and stored in a
	       * map. Subsequent calls to `addListener`, `hasListener`, or `removeListener`
	       * retrieve the original wrapper, so that  attempts to remove a
	       * previously-added listener work as expected.
	       *
	       * @param {DefaultWeakMap<function, function>} wrapperMap
	       *        A DefaultWeakMap object which will create the appropriate wrapper
	       *        for a given listener function when one does not exist, and retrieve
	       *        an existing one when it does.
	       *
	       * @returns {object}
	       */


	      const wrapEvent = wrapperMap => ({
	        addListener(target, listener, ...args) {
	          target.addListener(wrapperMap.get(listener), ...args);
	        },

	        hasListener(target, listener) {
	          return target.hasListener(wrapperMap.get(listener));
	        },

	        removeListener(target, listener) {
	          target.removeListener(wrapperMap.get(listener));
	        }

	      });

	      const onRequestFinishedWrappers = new DefaultWeakMap(listener => {
	        if (typeof listener !== "function") {
	          return listener;
	        }
	        /**
	         * Wraps an onRequestFinished listener function so that it will return a
	         * `getContent()` property which returns a `Promise` rather than using a
	         * callback API.
	         *
	         * @param {object} req
	         *        The HAR entry object representing the network request.
	         */


	        return function onRequestFinished(req) {
	          const wrappedReq = wrapObject(req, {}
	          /* wrappers */
	          , {
	            getContent: {
	              minArgs: 0,
	              maxArgs: 0
	            }
	          });
	          listener(wrappedReq);
	        };
	      }); // Keep track if the deprecation warning has been logged at least once.

	      let loggedSendResponseDeprecationWarning = false;
	      const onMessageWrappers = new DefaultWeakMap(listener => {
	        if (typeof listener !== "function") {
	          return listener;
	        }
	        /**
	         * Wraps a message listener function so that it may send responses based on
	         * its return value, rather than by returning a sentinel value and calling a
	         * callback. If the listener function returns a Promise, the response is
	         * sent when the promise either resolves or rejects.
	         *
	         * @param {*} message
	         *        The message sent by the other end of the channel.
	         * @param {object} sender
	         *        Details about the sender of the message.
	         * @param {function(*)} sendResponse
	         *        A callback which, when called with an arbitrary argument, sends
	         *        that value as a response.
	         * @returns {boolean}
	         *        True if the wrapped listener returned a Promise, which will later
	         *        yield a response. False otherwise.
	         */


	        return function onMessage(message, sender, sendResponse) {
	          let didCallSendResponse = false;
	          let wrappedSendResponse;
	          let sendResponsePromise = new Promise(resolve => {
	            wrappedSendResponse = function (response) {
	              if (!loggedSendResponseDeprecationWarning) {
	                console.warn(SEND_RESPONSE_DEPRECATION_WARNING, new Error().stack);
	                loggedSendResponseDeprecationWarning = true;
	              }

	              didCallSendResponse = true;
	              resolve(response);
	            };
	          });
	          let result;

	          try {
	            result = listener(message, sender, wrappedSendResponse);
	          } catch (err) {
	            result = Promise.reject(err);
	          }

	          const isResultThenable = result !== true && isThenable(result); // If the listener didn't returned true or a Promise, or called
	          // wrappedSendResponse synchronously, we can exit earlier
	          // because there will be no response sent from this listener.

	          if (result !== true && !isResultThenable && !didCallSendResponse) {
	            return false;
	          } // A small helper to send the message if the promise resolves
	          // and an error if the promise rejects (a wrapped sendMessage has
	          // to translate the message into a resolved promise or a rejected
	          // promise).


	          const sendPromisedResult = promise => {
	            promise.then(msg => {
	              // send the message value.
	              sendResponse(msg);
	            }, error => {
	              // Send a JSON representation of the error if the rejected value
	              // is an instance of error, or the object itself otherwise.
	              let message;

	              if (error && (error instanceof Error || typeof error.message === "string")) {
	                message = error.message;
	              } else {
	                message = "An unexpected error occurred";
	              }

	              sendResponse({
	                __mozWebExtensionPolyfillReject__: true,
	                message
	              });
	            }).catch(err => {
	              // Print an error on the console if unable to send the response.
	              console.error("Failed to send onMessage rejected reply", err);
	            });
	          }; // If the listener returned a Promise, send the resolved value as a
	          // result, otherwise wait the promise related to the wrappedSendResponse
	          // callback to resolve and send it as a response.


	          if (isResultThenable) {
	            sendPromisedResult(result);
	          } else {
	            sendPromisedResult(sendResponsePromise);
	          } // Let Chrome know that the listener is replying.


	          return true;
	        };
	      });

	      const wrappedSendMessageCallback = ({
	        reject,
	        resolve
	      }, reply) => {
	        if (extensionAPIs.runtime.lastError) {
	          // Detect when none of the listeners replied to the sendMessage call and resolve
	          // the promise to undefined as in Firefox.
	          // See https://github.com/mozilla/webextension-polyfill/issues/130
	          if (extensionAPIs.runtime.lastError.message === CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE) {
	            resolve();
	          } else {
	            reject(new Error(extensionAPIs.runtime.lastError.message));
	          }
	        } else if (reply && reply.__mozWebExtensionPolyfillReject__) {
	          // Convert back the JSON representation of the error into
	          // an Error instance.
	          reject(new Error(reply.message));
	        } else {
	          resolve(reply);
	        }
	      };

	      const wrappedSendMessage = (name, metadata, apiNamespaceObj, ...args) => {
	        if (args.length < metadata.minArgs) {
	          throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`);
	        }

	        if (args.length > metadata.maxArgs) {
	          throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`);
	        }

	        return new Promise((resolve, reject) => {
	          const wrappedCb = wrappedSendMessageCallback.bind(null, {
	            resolve,
	            reject
	          });
	          args.push(wrappedCb);
	          apiNamespaceObj.sendMessage(...args);
	        });
	      };

	      const staticWrappers = {
	        devtools: {
	          network: {
	            onRequestFinished: wrapEvent(onRequestFinishedWrappers)
	          }
	        },
	        runtime: {
	          onMessage: wrapEvent(onMessageWrappers),
	          onMessageExternal: wrapEvent(onMessageWrappers),
	          sendMessage: wrappedSendMessage.bind(null, "sendMessage", {
	            minArgs: 1,
	            maxArgs: 3
	          })
	        },
	        tabs: {
	          sendMessage: wrappedSendMessage.bind(null, "sendMessage", {
	            minArgs: 2,
	            maxArgs: 3
	          })
	        }
	      };
	      const settingMetadata = {
	        clear: {
	          minArgs: 1,
	          maxArgs: 1
	        },
	        get: {
	          minArgs: 1,
	          maxArgs: 1
	        },
	        set: {
	          minArgs: 1,
	          maxArgs: 1
	        }
	      };
	      apiMetadata.privacy = {
	        network: {
	          "*": settingMetadata
	        },
	        services: {
	          "*": settingMetadata
	        },
	        websites: {
	          "*": settingMetadata
	        }
	      };
	      return wrapObject(extensionAPIs, staticWrappers, apiMetadata);
	    };

	    if (typeof chrome != "object" || !chrome || !chrome.runtime || !chrome.runtime.id) {
	      throw new Error("This script should only be loaded in a browser extension.");
	    } // The build process adds a UMD wrapper around this file, which makes the
	    // `module` variable available.


	    module.exports = wrapAPIs(chrome);
	  } else {
	    module.exports = browser;
	  }
	});

	}(browserPolyfill));

	var browser$1 = browserPolyfill.exports;

	console.log('执行');
	console.log(browser$1.runtime.onInstalled);

}));
